﻿using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using Neturion.Dados;
using Neturion.IRepositorios;

namespace Neturion.Repositorios
{
    public class RepositorioContaContabil : IRepositorioContaContabil
    {
        public ContaContabil Inserir(ContaContabil contaContabil)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Save(contaContabil);
            return contaContabil;
        }

        public ContaContabil Atualizar(ContaContabil contaContabil)
        {
            ContaContabil tmpContaContabil = ObterPorId(contaContabil.ContaContabilId);
            // Atribuicao dos valores do objeto da memoria para o objeto obtido no banco de dados
            tmpContaContabil.Codigo = contaContabil.Codigo;
            tmpContaContabil.Descricao = contaContabil.Descricao;
            tmpContaContabil.EnumTipoConta = contaContabil.EnumTipoConta;
            tmpContaContabil.EnumTipoOperacionalidade = contaContabil.EnumTipoOperacionalidade;
            tmpContaContabil.TipoContaContabil = contaContabil.TipoContaContabil;

            tmpContaContabil.ListaContasContabils.Clear();
            foreach (ContaContabil custo in contaContabil.ListaContasContabils)
            {
                tmpContaContabil.AdicionarContaContabilFilho(custo);
            }

            GerenciadorBDConfigs.Instance.SessaoAtual().Merge(tmpContaContabil);
            return tmpContaContabil;
        }

        public void Excluir(ContaContabil contaContabil)
        {
            GerenciadorBDConfigs.Instance.SessaoAtual().Delete(contaContabil);
        }

        public IList<ContaContabil> ObterTodos()
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaContabil));
            return criteria.List<ContaContabil>() as List<ContaContabil>;
        }

        public ContaContabil ObterPorId(int id)
        {
            return GerenciadorBDConfigs.Instance.SessaoAtual().Get<ContaContabil>(id);
        }

        public IList<ContaContabil> ObterTodos(int inicio, int quantidade, int quantidadeMinima, string codigo, string descricao,
                                        EnumTipoConta? enumTipoConta, EnumTipoOperacionalidade? enumTipoOperacionalidade, TipoContaContabil tipoContaContabil)
        {
            if (quantidade.Equals(0))
            {
                quantidade = quantidadeMinima;
            }

            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaContabil))
               .SetFirstResult(inicio).SetMaxResults(quantidade);

            if (!string.IsNullOrEmpty(codigo))
            {
                criteria.Add(Restrictions.Eq("Codigo", codigo));
            }

            if (!string.IsNullOrEmpty(descricao))
            {
                criteria.Add(Restrictions.Like("Descricao", descricao, MatchMode.Anywhere));
            }

            if(enumTipoConta != null)
            {
                criteria.Add(Restrictions.Eq("EnumTipoConta", enumTipoConta));
            }

            if (enumTipoOperacionalidade != null)
            {
                criteria.Add(Restrictions.Eq("EnumTipoOperacionalidade", enumTipoOperacionalidade));
            }

            if (tipoContaContabil != null)
            {
                criteria.Add(Restrictions.Eq("TipoContaContabil", tipoContaContabil));
            }

            return criteria.List<ContaContabil>() as List<ContaContabil>;
        }

        public ContaContabil ObterPorCodigo(string codigo)
        {
            ICriteria criteria = GerenciadorBDConfigs.Instance.SessaoAtual().CreateCriteria(typeof(ContaContabil))
               .Add(Restrictions.Eq("Codigo", codigo));

            return criteria.UniqueResult<ContaContabil>() as ContaContabil;
        }
    }
}